<?php
/**
 * 熵巡 - 企业级氚云OpenAPI数据管理平台
 * 开发归属 Alyr.net
 * 氚云图片处理工具类 - 图片下载、URL构建、字段解析
 * 尊重劳动成果是一种美德
 */

/**
 * 氚云图片API完整参数配置
 */
class H3yunImageConfig {
    
    // 氚云API端点
    const DOWNLOAD_API_URL = 'https://www.h3yun.com/Api/DownloadBizObjectFile';
    const FILES_BASE_URL = 'https://files.h3yun.com/';
    
    // 必需的认证参数
    public $engineCode;     // 企业引擎代码
    public $engineSecret;   // 企业引擎密钥
    
    public function __construct($engineCode, $engineSecret) {
        $this->engineCode = $engineCode;
        $this->engineSecret = $engineSecret;
    }
}

/**
 * 氚云图片处理类
 */
class H3yunImageHandler {
    
    private $config;
    
    public function __construct(H3yunImageConfig $config) {
        $this->config = $config;
    }
    
    /**
     * 构建氚云图片直接访问URL
     * @param string $imageId 图片ID (GUID格式)
     * @return string 图片URL
     */
    public function buildDirectImageUrl($imageId) {
        // 验证图片ID格式（GUID）
        if (!$this->isValidGuid($imageId)) {
            return '';
        }
        
        return H3yunImageConfig::FILES_BASE_URL . $imageId;
    }
    
    /**
     * 构建本地代理图片URL
     * @param string $imageId 图片ID
     * @return string 代理URL
     */
    public function buildProxyImageUrl($imageId) {
        return '/api/image_proxy.php?id=' . urlencode($imageId);
    }
    
    /**
     * 从氚云下载图片/附件
     * @param string $attachmentId 附件ID
     * @return array 包含状态、消息和文件数据的数组
     */
    public function downloadAttachment($attachmentId) {
        // 验证参数
        if (empty($attachmentId)) {
            return [
                'success' => false,
                'message' => '附件ID不能为空',
                'data' => null
            ];
        }
        
        // 准备请求参数
        $params = [
            'attachmentId' => $attachmentId,
            'EngineCode' => $this->config->engineCode
        ];
        
        // 准备cURL请求
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, H3yunImageConfig::DOWNLOAD_API_URL);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HEADER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        
        // 设置请求头 - 氚云要求的认证参数
        $headers = [
            'EngineCode: ' . $this->config->engineCode,
            'EngineSecret: ' . $this->config->engineSecret,
        ];
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        
        // 执行请求
        $response = curl_exec($ch);
        
        // 检查错误
        if ($response === false) {
            $error = curl_error($ch);
            curl_close($ch);
            return [
                'success' => false,
                'message' => '下载附件失败: ' . $error,
                'data' => null
            ];
        }
        
        // 获取响应信息
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
        curl_close($ch);
        
        // 分离响应头和正文
        $responseHeader = substr($response, 0, $headerSize);
        $responseBody = substr($response, $headerSize);
        
        // 检查HTTP状态码
        if ($httpCode != 200) {
            return [
                'success' => false,
                'message' => '下载附件失败，HTTP状态码: ' . $httpCode,
                'data' => null
            ];
        }
        
        // 从响应头中获取文件名（支持多种编码格式）
        $filename = '';
        
        // 尝试匹配 RFC 5987 格式：filename*=UTF-8''%E6%96%87%E4%BB%B6%E5%90%8D.pdf
        if (preg_match('/Content-Disposition:.*filename\*=([^;\r\n]+)/i', $responseHeader, $matches)) {
            $encodedFilename = trim($matches[1]);
            // 解析 charset''encoded-value 格式
            if (preg_match("/^([^']*)'([^']*)'(.+)$/", $encodedFilename, $parts)) {
                $charset = strtoupper($parts[1]);
                $encodedValue = $parts[3];
                $filename = urldecode($encodedValue);
                // 如果字符集不是UTF-8，尝试转换
                if ($charset && $charset !== 'UTF-8' && function_exists('mb_convert_encoding')) {
                    $filename = mb_convert_encoding($filename, 'UTF-8', $charset);
                }
            } else {
                // 可能是纯URL编码格式
                $filename = urldecode($encodedFilename);
            }
        }
        // 尝试匹配标准格式：filename="文件名.pdf"
        elseif (preg_match('/Content-Disposition:.*filename="([^"]+)"/i', $responseHeader, $matches)) {
            $filename = $matches[1];
            // 如果是URL编码的，解码
            if (strpos($filename, '%') !== false) {
                $filename = urldecode($filename);
            }
            // 尝试修复可能的字符编码问题
            if (function_exists('mb_check_encoding') && !mb_check_encoding($filename, 'UTF-8')) {
                // 尝试从GBK转换为UTF-8
                if (function_exists('mb_convert_encoding')) {
                    $filename = mb_convert_encoding($filename, 'UTF-8', 'GBK');
                }
            }
        }
        // 尝试匹配无引号格式：filename=文件名.pdf
        elseif (preg_match('/Content-Disposition:.*filename=([^;\r\n]+)/i', $responseHeader, $matches)) {
            $filename = trim($matches[1]);
            // 移除可能的引号
            $filename = trim($filename, '"\' ');
            if (strpos($filename, '%') !== false) {
                $filename = urldecode($filename);
            }
            // 尝试修复可能的字符编码问题
            if (function_exists('mb_check_encoding') && !mb_check_encoding($filename, 'UTF-8')) {
                if (function_exists('mb_convert_encoding')) {
                    $filename = mb_convert_encoding($filename, 'UTF-8', 'GBK');
                }
            }
        }
        
        // 清理BOM和特殊字符
        $filename = preg_replace('/^\xEF\xBB\xBF/', '', $filename);
        $filename = trim($filename);
        
        // 如果文件名仍然为空或无效，使用附件ID作为默认文件名
        if (empty($filename)) {
            $filename = 'attachment_' . substr($attachmentId, 0, 8) . '.file';
        }
        
        return [
            'success' => true,
            'message' => '附件下载成功',
            'data' => $responseBody,
            'filename' => $filename,
            'content_type' => $this->getContentTypeFromHeader($responseHeader),
            'size' => strlen($responseBody),
            'debug_header' => $responseHeader  // 返回响应头用于调试
        ];
    }
    
    /**
     * 处理氚云图片字段数据
     * @param mixed $imageField 从氚云表单获取的图片字段数据
     * @return array 包含图片ID和URL的数组
     */
    public function processImageField($imageField) {
        $plateImageId = '';
        $plateImageUrl = '';
        
        if (empty($imageField)) {
            return [
                'imageId' => '',
                'directUrl' => '',
                'proxyUrl' => '',
                'isValid' => false
            ];
        }
        
        // 判断图片ID类型
        if (is_string($imageField)) {
            // 直接使用ID
            $plateImageId = trim($imageField);
        } else if (is_array($imageField)) {
            // 从数组中提取ID - 处理不同格式的数组
            if (isset($imageField[0]['id'])) {
                $plateImageId = $imageField[0]['id'];
            } else if (isset($imageField[0]['refId'])) {
                $plateImageId = $imageField[0]['refId'];
            } else if (isset($imageField[0]) && is_string($imageField[0])) {
                $plateImageId = $imageField[0];
            } else if (count($imageField) > 0) {
                $plateImageId = (string)$imageField[0];
            }
        }
        
        // 验证并构建URL
        if (!empty($plateImageId) && $this->isValidGuid($plateImageId)) {
            $directUrl = $this->buildDirectImageUrl($plateImageId);
            $proxyUrl = $this->buildProxyImageUrl($plateImageId);
            
            return [
                'imageId' => $plateImageId,
                'directUrl' => $directUrl,
                'proxyUrl' => $proxyUrl,
                'isValid' => true
            ];
        }
        
        return [
            'imageId' => $plateImageId,
            'directUrl' => '',
            'proxyUrl' => '',
            'isValid' => false
        ];
    }
    
    /**
     * 验证GUID格式
     * @param string $guid
     * @return bool
     */
    private function isValidGuid($guid) {
        return preg_match('/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i', $guid);
    }
    
    /**
     * 从响应头中获取内容类型
     * @param string $header
     * @return string
     */
    private function getContentTypeFromHeader($header) {
        if (preg_match('/Content-Type: ([^\r\n]+)/i', $header, $matches)) {
            return $matches[1];
        }
        return 'application/octet-stream';
    }
}

/**
 * 便捷函数：获取氚云图片处理器实例
 * @param array $config 配置数组，包含 appCode 和 appSecret
 * @return H3yunImageHandler
 */
function getH3yunImageHandler($config) {
    $imageConfig = new H3yunImageConfig($config['appCode'], $config['appSecret']);
    return new H3yunImageHandler($imageConfig);
}

/**
 * 便捷函数：处理氚云图片字段并返回HTML
 * @param mixed $imageField 图片字段数据
 * @param array $config 配置数组
 * @param array $options 选项 [width, height, alt, class]
 * @return string HTML图片标签
 */
function renderH3yunImage($imageField, $config, $options = []) {
    $handler = getH3yunImageHandler($config);
    $imageData = $handler->processImageField($imageField);
    
    if (!$imageData['isValid']) {
        $width = $options['width'] ?? '100px';
        $height = $options['height'] ?? '100px';
        return '<div style="width:' . $width . ';height:' . $height . ';display:flex;align-items:center;justify-content:center;background:#f0f0f0;color:#888;font-size:12px;">没有图片</div>';
    }
    
    // 构建图片HTML
    $width = isset($options['width']) ? 'width="' . $options['width'] . '"' : '';
    $height = isset($options['height']) ? 'height="' . $options['height'] . '"' : '';
    $alt = $options['alt'] ?? '氚云图片';
    $class = isset($options['class']) ? 'class="' . $options['class'] . '"' : '';
    $style = isset($options['style']) ? 'style="' . $options['style'] . '"' : '';
    
    // 使用直接URL，失败时回退到代理URL
    $html = '<img src="' . $imageData['directUrl'] . '" alt="' . $alt . '" ' . $width . ' ' . $height . ' ' . $class . ' ' . $style . ' 
        onerror="this.onerror=null; this.src=\'' . $imageData['proxyUrl'] . '\'; this.onerror=function(){this.style.display=\'none\'; this.insertAdjacentHTML(\'afterend\', \'<div style=\\\'width:100px;height:100px;display:flex;align-items:center;justify-content:center;background:#f0f0f0;color:#888;font-size:12px;\\\'>图片无法加载</div>\');}" />';
    
    return $html;
}
?>